<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
<canvas id="physicsCanvas" width="500" height="450"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;

    // Helper function to draw an arrow
    function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }

    // Diagram constants
    const cx = 250;
    const cy = 230;
    const rx = 150;
    const ry = 60;

    // Draw Magnetic Field B lines
    ctx.font = 'italic bold 24px Arial';
    ctx.fillText('B', cx + rx + 50, 130);
    // Outer lines
    drawArrow(ctx, cx - rx - 40, 380, cx - rx - 40, 100);
    drawArrow(ctx, cx + rx + 40, 380, cx + rx + 40, 100);

    // Draw the ring
    ctx.beginPath();
    ctx.ellipse(cx, cy, rx, ry, 0, 0, 2 * Math.PI);
    ctx.stroke();

    // Draw inner B-field lines (originating from the ring plane)
    drawArrow(ctx, cx - rx * 0.5, cy, cx - rx * 0.5, 120);
    drawArrow(ctx, cx + rx * 0.5, cy, cx + rx * 0.5, 120);


    // Draw axis of rotation and radius R (dashed)
    ctx.save();
    ctx.setLineDash([5, 5]);
    // Axis
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.lineTo(cx, 80);
    ctx.stroke();
    // Radius
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    const r_end_x = cx + rx * Math.cos(-Math.PI / 8);
    const r_end_y = cy + ry * Math.sin(-Math.PI / 8);
    ctx.lineTo(r_end_x, r_end_y);
    ctx.stroke();
    ctx.restore();

    // Draw angular velocity ω
    // Vertical arrow on axis
    drawArrow(ctx, cx, cy - ry, cx, 60);
    // Curved arrow for rotation
    const omega_arc_y = 90;
    const omega_arc_radius = 25;
    ctx.beginPath();
    ctx.arc(cx, omega_arc_y, omega_arc_radius, -Math.PI * 0.9, -Math.PI * 0.4);
    ctx.stroke();
    // Arrowhead for the curved arrow
    const arc_end_angle = -Math.PI * 0.4;
    const arc_end_x = cx + omega_arc_radius * Math.cos(arc_end_angle);
    const arc_end_y = omega_arc_y + omega_arc_radius * Math.sin(arc_end_angle);
    const tangent_angle = arc_end_angle + Math.PI / 2;
    ctx.beginPath();
    ctx.moveTo(arc_end_x, arc_end_y);
    ctx.lineTo(arc_end_x - 8 * Math.cos(tangent_angle - Math.PI / 6), arc_end_y - 8 * Math.sin(tangent_angle - Math.PI / 6));
    ctx.moveTo(arc_end_x, arc_end_y);
    ctx.lineTo(arc_end_x - 8 * Math.cos(tangent_angle + Math.PI / 6), arc_end_y - 8 * Math.sin(tangent_angle + Math.PI / 6));
    ctx.stroke();

    // Draw labels (R, ω)
    ctx.font = 'italic bold 24px Arial';
    ctx.fillText('R', cx + 100, cy);
    ctx.fillText('ω', cx + 35, 80);

    // Mass and Charge (m, Q) indicator
    const m_indicator_x = cx - 110;
    const m_indicator_y_start = cy + ry; // level with bottom of ellipse
    const m_indicator_y_end = m_indicator_y_start + 40;
    ctx.beginPath();
    ctx.moveTo(m_indicator_x, m_indicator_y_start);
    ctx.lineTo(m_indicator_x, m_indicator_y_end);
    ctx.moveTo(m_indicator_x - 15, m_indicator_y_end);
    ctx.lineTo(m_indicator_x + 15, m_indicator_y_end);
    ctx.stroke();
    ctx.font = 'italic 24px Arial';
    ctx.fillText('m,Q', m_indicator_x + 20, m_indicator_y_end - 5);


    // Draw bottom caption
    ctx.font = '24px "Songti SC", "SimSun", sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('电图 2.21.1', canvas.width / 2, 420);

</script>
</body>
</html>